<?php
declare (strict_types=1);

namespace app\scan_bag\controller;

use aliyun\AliyunOss;
use app\admin\model\advertiser\AdvertiserTask;
use app\admin\model\advertiser\AdvertiserTaskLog;
use app\admin\model\advertiser\AdvertiserThird;
use app\admin\model\advertiser\AdvertiserThirdLog;
use app\admin\model\base\User;
use app\admin\model\base\UserOfficial;
use app\admin\model\iot\AdvertiserTaskDevice;
use app\admin\model\iot\IntegralTask as IntegralTaskModel;
use app\admin\model\iot\IntegralTaskComplet;
use app\admin\model\iot\ScanBagStrategy as ScanBagStrategyModel;
use app\admin\model\iot\ScanBagWay;
use app\admin\service\base\JwtService;
use app\admin\validates\IntegralTaskCompleValidate;
use app\BaseController;
use app\BaseService;
use app\scan_bag\service\ScanBagV1Service;
use app\scan_bag\service\ScanBagV2Service;
use app\scan_bag\service\V1_Way_1_0Service;
use ciphertext\RsaIotData;
use think\App;
use think\exception\ValidateException;
use think\facade\Cache;
use think\facade\Cookie;
use think\facade\Log;
use think\facade\Request;
use think\response\Json;
use wechat\ScanBagMiniProgram;
use wechat\WsOfficialAccount;
use wechat\WsOpenPlatform;
use app\admin\model\advertiser\AdvertiserMatter;

/**
 * 微信V1_Way_6_0扫码取袋
 */
class V1_Way_6_0 extends BaseController
{

    /**
     * 当前扫码路径
     * @var string
     */
    private string $way = 'V1_Way_6_0';

    /**
     * 微信H5用户登录
     * @param ScanBagV2Service $scanBagV2Service
     * @return Json
     */
    public function wechatLogin(ScanBagV2Service $scanBagV2Service): Json
    {
        //接受参数
        $code = $this->request->param('code/s', '');
        //微信解析code
        $bool = $scanBagV2Service->wechatH5Login2($code);
        if ($bool['bool']) {
            //签发token
            $jst_data = JwtService::authorizations('scan_bag', $bool['user_id'], 3600);
            if ($jst_data['bool']) {
                return jsonReturn(1, $bool, '登录成功');
            }
        }
        return jsonReturn(0, [], '签发token失败');
    }

    /**
     * 获取用户取袋次数并同步用户到客户
     * @param ScanBagV1Service $scanBagV1Service
     * @return Json
     */
    public function userScanNum(ScanBagV1Service $scanBagV1Service): Json
    {
        //接收参数
        $user_id = WS_USER_ID;
        $mac_id = $this->request->param('mac_id', '');
        if (!$mac_id) {
            return jsonReturn(0, [], '参数错误');
        }

        //标记取袋安全码
        $SafeCode = ScanBagV2Service::getBagOutSafeCode($user_id, $this->way, $mac_id, 1);
        if (!$SafeCode) {
            return jsonReturn(0, [], '请重新扫描屏幕上的二维码');
        }
        return  $scanBagV1Service->userScanNum($user_id, $mac_id);

    }

    /**
     * 获取JSAPI配置
     * @return Json
     */
    public function jsApiConfig(): Json
    {
        //接受参数
        $url = $this->request->param('url/s', '');
        $obj = new WsOfficialAccount();
        $data = $obj->getJsApi($url);;
        return jsonReturn(1, $data);
    }

    /**
     * 获取推广微信小程序
     * @return Json
     */
    public function getWechatApplet(): Json
    {
        //接收参数
        $user_id = WS_USER_ID;
        $mac_id = $this->request->param('mac_id', '');
        if (!$mac_id) {
            return jsonReturn(0, [], '参数错误');
        }
        //通过mac_id获取路径
        $WayInfo = ScanBagWay::getMacIdWay($mac_id);
        if ($WayInfo['key'] != $this->way) {
            return jsonReturn(0, [], '当前设备路径错误,请联系管理员!');
        }
        //判断需要验证取袋路径
        if ($WayInfo and $WayInfo['third_mini']) {
            //获取推广小程序信息
            $Third = AdvertiserThird::getIDThird($WayInfo['third_mini']);
            if ($Third and !in_array($mac_id, $Third['prohibit']) and $Third['mini_ogh'] and $Third['mini_appid']) {
                $temp = [
                    'way' => $WayInfo['key'],
                    'third_id' => $Third['id'],
                    'type' => $Third['type'],
                    'mini_name' => $Third['mini_name'],
                    'mini_ogh' => $Third['mini_ogh'],
                    'mini_appid' => $Third['mini_appid'],
                    'mini_link' => $Third['mini_link'],
                ];
                //写入统计
                AdvertiserThirdLog::writeMiniprogramLog($user_id, $Third['id'], $mac_id);
                //标记取袋安全码
                $SafeCode = ScanBagV2Service::getBagOutSafeCode($user_id, $this->way, $mac_id, 3);
                if (!$SafeCode) {
                    return jsonReturn(0, [], '请重新扫描屏幕上的二维码');
                }
                return jsonReturn(1, $temp);
            }
        }
        return jsonReturn(0, [], '路径参数错误');
    }

    /**
     * 获取微信H5公众号二维码
     * @return Json
     */
    public function wechatQrcode(): Json
    {
        //默认值
        $user_id = WS_USER_ID;
        $name = $appid = $qrcode = '';
        $is_qrcode = false;
        //接受参数
        $meipaopenid = $this->request->param('meipaopenid/s', '');
        $mac_id = $this->request->param('mac_id/s', '');
        if (!$mac_id) {
            return jsonReturn(0, [], '设备参数错误,请联系管理员!');
        }
        //对接聚合平台
        $WayInfo = ScanBagWay::getMacIdWay($mac_id);
        if (!$WayInfo or $WayInfo['key'] != $this->way) {
            return jsonReturn(0, [], '当前设备路径错误,请联系管理员!');
        }
        //先拿美葩公众号
        $OfficialAccount = AdvertiserThird::getIdOfficialAccount($user_id, 6, $mac_id, $meipaopenid);
        if ($OfficialAccount) {
            $name = $OfficialAccount['name'];
            $appid = $OfficialAccount['appid'];
            $qrcode = $OfficialAccount['qrcode'];
            $is_qrcode = $OfficialAccount['is_qrcode'];
        } else {
            //没拿到时则获取设置的第三方平台
            $OfficialAccount = AdvertiserThird::getIdOfficialAccount($user_id, $WayInfo['third_official'], $mac_id);
            if ($OfficialAccount) {
                $name = $OfficialAccount['name'];
                $appid = $OfficialAccount['appid'];
                $qrcode = $OfficialAccount['qrcode'];
                $is_qrcode = $OfficialAccount['is_qrcode'];
            }
        }
        if (!$name or !$appid or !$qrcode) {
            try {
                $type = 1;
                $tasks = AdvertiserTask::wechatTaskDistributionNew($type);
                if ($tasks) {
                    foreach($tasks as $task){
                        //判断是否有限制设备
                        $adAdvertiserTaskDevice=AdvertiserTaskDevice::where('task_id',$task['id'])->column('mac_id');
                        if($adAdvertiserTaskDevice && !in_array($mac_id,$adAdvertiserTaskDevice)){
                            continue ;
                        }
                        //判断是否有关注
                        $exist = UserOfficial::itExist($user_id, $task['appid']);
                        if(!$exist){
                            $name = $task['name'];
                            $appid = $task['appid'];
                            UserOfficial::oneLogSave($user_id, $appid, 1);
                            //获取带参数的二维码url
                            $Ws = new WsOpenPlatform();
                            $qrcode = $Ws->officialAccountTemporaryQrcode($task['appid'], 'scan_bag');
                            //写入推广任务明细记录
                            AdvertiserTaskLog::writeTaskLog($user_id, $mac_id, intval($task['id']), floatval($task['single_price']));
                            break ;
                        }

                    }

                }//end if
            } catch (\Exception $exception) {
                Log::write($exception->getMessage(), '广告主微信H5公众号二维码');
            }
        }//end if
        //没有关注和没有第三方二维码则显示兜底二维码
        if (!$name or !$appid or !$qrcode) {
            $sys_config = config('sys_config.WsOfficialAccount');
            //未关注默认主体公众号二维码
            $name = $sys_config['name'];
            $appid = $sys_config['appid'];
            //获取带参数的二维码url
            $Ws = new WsOfficialAccount();
            $qrcode = $Ws->temporaryQrcode('scan_bag');
        }
        //返回数据
        $data = ['name' => $name, 'appid' => $appid, 'qrcode' => $qrcode, 'is_qrcode' => $is_qrcode];
        return jsonReturn(1, $data);
    }

    /**
     * 微信上传经纬度信息
     * @param V1_Way_1_0Service $v1_Way_1_0Service
     * @return Json
     */
    public function wechatLatLon(V1_Way_1_0Service $v1_Way_1_0Service): Json
    {
        //接受参数
        $mac_id = $this->request->param('mac_id/s', '0');
        $latitude = $this->request->param('latitude/s', '0');
        $longitude = $this->request->param('longitude/s', '0');
        $accuracy = $this->request->param('accuracy/d', 0);    //位置精度
        //经纬度保存数据库
        $user_id = WS_USER_ID;
        //把地理位置信息保存至用户表
        User::userLocationRedis($user_id, $mac_id, $latitude, $longitude);
        //微信验证上传经纬度信息
        $bool = $v1_Way_1_0Service->wechatLatLon($mac_id, $latitude, $longitude);
        if ($bool) {
            return jsonReturn(1, [], '验证通过');
        }
        return jsonReturn(0, [], '您的位置距离设备太远,请移步设备前扫码免费领取。');
    }

    /**
     * 微信H5识别二维码
     * @return Json
     */
    public function qrcodeDiscern(): Json
    {
        //接受参数
        $user_id = WS_USER_ID;
        $mac_id = $this->request->param('mac_id/s');
        if (!$mac_id) {
            return jsonReturn(0, [], 'MacID参数错误');
        }
        //标记取袋安全码
        $SafeCode = ScanBagV2Service::getBagOutSafeCode($user_id, $this->way, $mac_id, 2);
        if (!$SafeCode) {
            return jsonReturn(0, [], '请重新扫描屏幕上的二维码');
        }
        return jsonReturn(1, []);
    }

    /**
     * 微信小程序URLScheme
     * @return Json
     */
    public function getURLScheme(V1_Way_1_0Service $v1_Way_1_0Service): Json
    {
        //接收参数
        $params = $this->request->param();
        if (!isset($params['mac_id']) or !$params['mac_id']) {
            return jsonReturn(0, [], '设备参数错误,请联系管理员!');
        }
        //获取用户信息
        $user_id = WS_USER_ID;
        //标记取袋安全码
//        $SafeCode = ScanBagV2Service::getBagOutSafeCode($user_id, $this->way, $params['mac_id'], 3,true);
//        if (!$SafeCode) {
//            return jsonReturn(0, [], '请重新扫描屏幕上的二维码');
//        }
        //验证地理位置,获取缓存当前用户经纬度
        //通过mac_id获取路径
        $WayInfo = ScanBagWay::getMacIdWay($params['mac_id']);
        if($WayInfo && isset($WayInfo['location_limit']) && $WayInfo['location_limit']==1){
            $LatLon = Cache::get(BaseService::generateLocationKey($user_id));
            $LatLon = $LatLon ?: ['latitude' => '', 'longitude' => ''];
            $bool = $v1_Way_1_0Service->wechatLatLon($params['mac_id'], $LatLon['latitude'], $LatLon['longitude']);
            if (!$bool) {
               return jsonReturn(0, [], '您的位置距离设备太远,请移步设备前扫码免费领取。');
            }
        }
        $User = User::getIdUserInfo($user_id);
        $params['open_id'] = $User['openid'];
        if ($WayInfo['key'] != $this->way) {
            return jsonReturn(0, [], '路径参数错误,请联系管理员');
        }
        //生成取袋路径微信小程序码
        $wechat = new ScanBagMiniProgram($WayInfo);
        $path = $WayInfo['mini_link'] ?? 'pages/index/index';
        //增加取袋码
        $params['way'] = $WayInfo['key'];
        $SafeCode = ScanBagV2Service::getBagOutSafeCode($user_id, $this->way, $params['mac_id'], 3,true);
        $params['pay_type']=$this->request->param('pay_type/d', 1);
        if (!$SafeCode) {
            $params['waycode'] = rand(100000,999999);
        }else{
            $params['waycode'] = ScanBagV2Service::generateBagOutWaycode($User, $WayInfo['key'], $params['mac_id'],$params['ticket'],$params['pay_type']);
        }
        $params['success_redirect_uri']=$WayInfo['success_redirect_uri']??'';
        //收到打开时需要的参数
        $data['miniPath'] = $path . '?' . http_build_query(array_unique($params));
        //则生成取袋路径微信小程序码
        $data['scheme'] = $wechat->URLScheme($path, http_build_query($params));
        $code = $data['scheme']['bool'] ? 1 : 0;
        return jsonReturn($code, $data);
    }

    /**
     * 微信取袋码出袋
     * @param ScanBagV1Service $scanBagV1Service
     * @param V1_Way_1_0Service $v1_Way_1_0Service
     * @return Json
     */
    public function postOutBag(ScanBagV1Service $scanBagV1Service,V1_Way_1_0Service $v1_Way_1_0Service): Json
    {
        //接收参数
        $user_id = WS_USER_ID;
        $mac_id = $this->request->param('mac_id/s', '');
        $sleep = $this->request->param('sleep/d', 15);
        $pay_type = $this->request->param('pay_type/d', 1);


        //标记取袋安全码
        $SafeCode = ScanBagV2Service::getBagOutSafeCode($user_id, $this->way, $mac_id, 4, true);
        if (!$SafeCode) {
            return jsonReturn(0, [], '请重新扫描屏幕上的二维码');
        }
        //获取用户信息
        $User = User::getIdUserInfo($user_id);
        //生成取袋码
        $waycode = ScanBagV2Service::generateBagOutWaycode($User, $this->way, $mac_id,'',2);
        //延迟出袋
        sleep(15);
        return $scanBagV1Service->outBagWaycodeToV1($waycode, $this->way,$pay_type);
    }

    /**
     * 微信取袋码出袋(积分)
     * @param ScanBagV1Service $scanBagV1Service
     * @param V1_Way_1_0Service $v1_Way_1_0Service
     * @return Json
     */
    public function postOutBag3(ScanBagV1Service $scanBagV1Service,V1_Way_1_0Service $v1_Way_1_0Service): Json
    {
        //接收参数
        $user_id = WS_USER_ID;
        $mac_id = $this->request->param('mac_id/s', '');
        $sleep = $this->request->param('sleep/d', 15);
        $pay_type = 2;
        $key = 'jf:'.$mac_id.':'.$user_id;
        $value = Cache::get($key);
        if(!$value){
            //标记取袋安全码
            $SafeCode = ScanBagV2Service::getBagOutSafeCode($user_id, $this->way, $mac_id, 4, true);
            if (!$SafeCode) {
//            return jsonReturn(0, [], '请重新扫描屏幕上的二维码');
            }
            //获取用户信息
            $User = User::getIdUserInfo($user_id);
            //生成取袋码
            $waycode = ScanBagV2Service::generateBagOutWaycode($User, $this->way, $mac_id,'',2);
            //延迟出袋
            Cache::set($key,1,30);//30s内只能操作一次
            sleep(15);
            return $scanBagV1Service->outBagWaycodeToV1($waycode, $this->way,$pay_type);
        }
        return jsonReturn(0, ['msg' => '频繁请求']);
    }

    /**
     * 微信取袋码出袋(视频号)
     * @param ScanBagV1Service $scanBagV1Service
     * @param V1_Way_1_0Service $v1_Way_1_0Service
     * @return Json
     */
    public function postOutBag2(ScanBagV1Service $scanBagV1Service,V1_Way_1_0Service $v1_Way_1_0Service): Json
    {
        //接收参数
        $user_id = WS_USER_ID;
        $mac_id = $this->request->param('mac_id/s', '');
        $sleep = $this->request->param('sleep/d', 15);
        $pay_type = $this->request->param('pay_type/d', 1);


        //标记取袋安全码
        $SafeCode = ScanBagV2Service::getBagOutSafeCode($user_id, $this->way, $mac_id, 4, true);
        if (!$SafeCode) {
            return jsonReturn(0, [], '请重新扫描屏幕上的二维码');
        }
        //获取用户信息
        $User = User::getIdUserInfo($user_id);
        //生成取袋码
        $waycode = ScanBagV2Service::generateBagOutWaycode($User, $this->way, $mac_id,'',2);
        //延迟出袋
        sleep(15);
        return $scanBagV1Service->outBagWaycodeToV1($waycode, $this->way,$pay_type);
    }

    /**
     * 发起微信支付
     * @param ScanBagV1Service $scanBagV1Service
     * @return Json
     */
    public function wechatPayOrder(ScanBagV1Service $scanBagV1Service): Json
    {
        $user_id = WS_USER_ID;
        $mac_id = $this->request->param('mac_id');
        if (!$mac_id) {
            return jsonReturn(0, [], '设备信息错误');
        }
        return $scanBagV1Service->payOrderToV1($user_id, $mac_id);
    }

    /**
     * 判断是否打开位置限制
     * @return Json
     */
    public function locationLimit():Json
    {
        $mac_id = $this->request->param('mac_id/s','');
        //判断参数
        if (!$mac_id) {
            return jsonReturn(0, [], '参数错误');
        }
        //通过mac_id获取路径
        $WayInfo = ScanBagWay::getMacIdWay($mac_id);
        if($WayInfo && $WayInfo['location_limit']){
            return jsonReturn(1, ['location_limit'=>$WayInfo['location_limit']]);
        }
        return jsonReturn(1, ['location_limit'=>0]);
    }

    /**
     * 验证码票据验证
     * @param V1_Way_1_0Service $v1_Way_1_0Service
     * @return Json
     */
    public function verifyCapture(V1_Way_1_0Service $v1_Way_1_0Service): Json
    {
        //接收参数
        $ticket = $this->request->param('ticket/s', '');//验证码票据
        $randstr = $this->request->param('randstr/s', '');//前端回调函数返回的随机字符串
        $user_ip = $this->request->ip();
        $params = array(
            "Ticket" => $ticket,
            "UserIp" => $user_ip,
            'Randstr' => $randstr
        );
        $result = $v1_Way_1_0Service->verifyCapture($params);
        if (isset($result->CaptchaCode) && $result->CaptchaCode == 1) {
            //写入缓存
            $key = 'capture_ticket:' . $ticket;
            Cache::set($key, 1, 500);
            return jsonReturn(1, $result);
        } else {
            return jsonReturn(0, $result);
        }
    }

     /**
     * 获取我的积分
     * @param V1_Way_1_0Service $v1_Way_1_0Service
     * @return Json
     */
    public function getMyPoints(V1_Way_1_0Service $v1_Way_1_0Service): Json
    {
        $User = User::getIdUserInfo(WS_USER_ID);
        $result = $v1_Way_1_0Service->getMyPoints($User['unionid']);
        return jsonReturn(1, $result);
    }

    /**
     * 做积分任务
     * @param V1_Way_1_0Service $v1_Way_1_0Service
     * @return Json
     */
    public function doTask(V1_Way_1_0Service $v1_Way_1_0Service):Json
    {
        $user_id = WS_USER_ID;
        $User = User::getIdUserInfo(WS_USER_ID);
        $params['task_id'] = $this->request->param('task_id/d');
        $params['type'] = $this->request->param('type/d');
        $params['content'] = $this->request->param('content/s');
        $params['user_id'] = $user_id;
        $params['bonus_points'] = $this->request->param('bonus_points/d');;
        $params['unionid'] = $User['unionid'];
        //写入任务流水账
        //数据验证
        try {
            validate(IntegralTaskCompleValidate::class)->scene('add')->check($params);
        } catch (ValidateException $e) {
            return jsonReturn(0, [], $e->getError());
        }
        //检查任务完成情况
        $check_task_complet = $v1_Way_1_0Service->checkTaskComplet($params);
        if(!$check_task_complet){
            return jsonReturn(0, '完成任务失败');
        }
        if($params['type']==3){
            $task_code =$v1_Way_1_0Service->generateTaskcode($User,$params['task_id'],$params['content'],$params);
            return jsonReturn(1, $task_code);
        }
        //扣减积分
        $result = $v1_Way_1_0Service->updateMyPoints($params);
        $res = false;
        if($result){
            $res = (new IntegralTaskComplet())->save($params);
        }
        $User = User::getIdUserInfo(WS_USER_ID);
        $result = $v1_Way_1_0Service->getMyPoints($User['unionid']);
        if($res && $result){
            return jsonReturn(1, $result);
        }else{
            return jsonReturn(0, $result);
        }

    }

    /**
     * 获取任务完成情况
     */
    public function getTaskComplet(V1_Way_1_0Service $v1_Way_1_0Service)
    {
        $user_id = WS_USER_ID;
        $result = $v1_Way_1_0Service->getTaskComplet($user_id);
        return jsonReturn(1, $result);
    }


    /**
     * 积分任务列表
     * @return Json
     */
    public function list(V1_Way_1_0Service $v1_Way_1_0Service): Json
    {
        $params['name']=Request::param('name/s');
        $params['type']=Request::param('type/d');
        $params['enabled']=Request::param('enabled/d',1);
        $params['page']=Request::param('page/d',1);
        $params['page_size']=Request::param('page_size/d',10);
        $where =[];
        if ($params['name']) {
            $where[] = ['name', 'like', '%' . $params['name'] . '%'];
        }
        //搜索类型
        if ($params['type'] and in_array($params['type'], [1, 2])) {
            $where[] = ['type', '=', $params['type']];
        }
        //搜索状态
        if (isset($params['enabled'])) {
            $where[] = ['enabled', '=', $params['enabled']];
        }
        $data = IntegralTaskModel::getList($where,$params['page'],$params['page_size']);
        //生成积分任务码
        $deal_data = $v1_Way_1_0Service->TaskListAddCode(WS_USER_ID,$data);
        return jsonReturn(1, $deal_data);
    }

    /**
     * 通过id展示二维码
     * @return Json
     */
    public function getTaskWechatQrcode()
    {
        $id = $this->request->param('id/d');
        $matter =AdvertiserMatter::getMatterInfo($id);
        //获取带参数的二维码url
        $Ws = new WsOpenPlatform();
        $qrcode = $Ws->officialAccountTemporaryQrcode($matter['appid'], 'scan_bag');
        $name = $matter['name'];
        $appid = $matter['appid'];
        $data = ['name' => $name, 'appid' => $appid, 'qrcode' => $qrcode, 'is_qrcode' => false];
        return jsonReturn(1, $data);
    }

    /**
     * 获取配置的视频号链接
     */
    function getVideoUrl()
    {
        $user_id = WS_USER_ID;
        $mac_id = $this->request->param('mac_id', '');
        if (!$mac_id) {
            return jsonReturn(0, [], '参数错误');
        }
        $url = ScanBagWay::where('key','=','V1_Way_6_0')->find();
        $AliyunOss = new AliyunOss();
        $img_url = $url->video_url ? $AliyunOss->getObjectUrl($url->video_url) : '';
        return jsonReturn(1, ['url'=>$img_url,'is_one_type'=>$url->is_one_type]);
    }




}
